package com.kuizii.auth.shiro;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.http.HttpMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * @Author: nuanyang
 * @Date: 2019/7/25 0025 16:58
 */

@Slf4j
public class KuiziiShiroFilter extends AccessControlFilter {

    public KuiziiShiroFilter(String loginUrl) {
        DEFAULT_LOGIN_URL = loginUrl;
    }

    public static String DEFAULT_LOGIN_URL = "";

    @Override
    public String getLoginUrl() {

        return DEFAULT_LOGIN_URL;
    }

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object o) {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        if (HttpMethod.OPTIONS.name().equalsIgnoreCase(httpRequest.getMethod())) {
            return true;
        }
        if (this.isLoginRequest(request, response)) {
            return true;
        }

        if (null != getSubject(request, response)) {
            Subject subject = this.getSubject(request, response);
            return subject.isAuthenticated() && subject.getPrincipal() != null;
        }


//        String token = AuthUtils.getToken(request);
//        if (StringUtils.isBlank(token)) {
//            if (StringUtils.isBlank(getLoginUrl())) {
//                onLoginFail(response, "请求头不包含认证信息authorization");
//            }
//            //转到拒绝访问处理逻辑
//            return false;
//        }
//
//        // 获取无状态Token
//        JWTToken accessToken = new JWTToken(token);
//        try {
//            // 委托给Realm进行登录
//            getSubject(request, response).login(accessToken);
//
//            //通过isPermitted 才能调用doGetAuthorizationInfo方法获取权限信息
//            boolean isPermitted = getSubject(request, response).isPermitted(httpRequest.getRequestURI());
//            if (!isPermitted) {
//                log.error("权限不足！");
//                return false;
//            }
//
//        } catch (AuthenticationException e) {
//            log.error(e.getMessage(), e);
//            return false;
//        } catch (Exception e) {
//            log.error("auth error:" + e.getMessage(), e);
////            onLoginFail(response, "身份凭证无效或已过期！" );
//            return false;
//        }
        return true;
    }

    /**
     * @param request
     * @param response
     * @return 表示当访问拒绝时是否已经处理了；如果返回true表示需要继续处理；如果返回false表示该拦截器实例已经处理了，将直接返回即可。
     * @throws Exception
     */
    @Override
    public boolean onAccessDenied(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response) throws Exception {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        log.info("拦截到的url:" + httpRequest.getRequestURL().toString());

        if (isLoginRequest(request, response) || StringUtils.isNotBlank(getLoginUrl())) {
            //跳转到登录页面
            redirectToLogin(request, response);
        } else {
            onLoginFail(response, "身份验证无效或权限不足!");
//            WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED, "身份验证无效或权限不足！");
        }
        return false;

    }

    /**
     * 登录失败时默认返回401状态码
     */
    private void onLoginFail(ServletResponse response, String errorMsg) throws IOException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        httpResponse.setContentType("text/html");
        httpResponse.setCharacterEncoding("utf-8");
        httpResponse.getWriter().write(errorMsg);
        httpResponse.getWriter().close();
    }
}
